package cn.lucky.thread.security;

/**
 * @Author: jianglingpeng
 * @Date: 2020/9/19
 * @Description:
 *  解决线程安全的方式一：使用synchronized(obj) 同步代码块的方式来解决线程安全,obj也叫同步锁
 *  同步的前提：必须有多个线程访问并且多个线程使用的是同一把锁
 *  同步的好处：解决了线程安全的问题
 *  注意：
 *      同步是一种高开销的操作，应该尽量减少同步的内容.
 *      通常没有必要同步整个方法，使用synchronized同步关键代码即可.
 *  测试synchronized代码块解决线程安全问题.
 *      继续使用四个线程卖100张票的例子
 * */
public class SynchronizedBlock {
    public static void main(String[] args) {
        SynchronizedBlockTicket ticket = new SynchronizedBlockTicket();
        /*启动四个线程,同时卖票*/
        new Thread(ticket).start();
        new Thread(ticket).start();
        new Thread(ticket).start();
        new Thread(ticket).start();
    }
}

class SynchronizedBlockTicket implements Runnable{
    /*初始化票数*/
    private int ticketNumber = 100;
    private static final Object object;
    static {
        object = new Object();
    }
    @Override
    public void run() {
        while (true) {
            synchronized (object){ //同步代码块中的锁可以是任意对象
                if (ticketNumber > 0){
                    try {
                        Thread.sleep(10 );
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程[" + Thread.currentThread().getName() + "] 卖出了第" + ticketNumber + "号票");
                    ticketNumber--;
                }else{
                    break;
                }
            }
        }
    }
}